#include <iostream>
#include <ifaddrs.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <net/if.h>
#include <regex>
#include <thread>

using namespace std;


/**
 * 获取本机网卡地址
 */
bool getLocalAddress(string& localAddress) {
    bool find_addr_ok = false;
    struct ifaddrs* ifaddr = nullptr;
    struct ifaddrs* ifa = nullptr;
    if (getifaddrs(&ifaddr) < 0){   //获取所有网卡的网卡地址
        std::cout << "Unable to get interface addresses..." << std::endl;
        return false;
    }

    // 遍历获取的本机网卡信息
    for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
        if (!ifa->ifa_addr)  //网卡地址有效
            continue;
        if (!(ifa->ifa_flags & IFF_UP)) //接口启用、支持组播
            continue;
        if ((ifa->ifa_flags & IFF_LOOPBACK) || (ifa->ifa_flags & IFF_POINTOPOINT))  //不是回环口地址、不是点对点网络
            continue;

        if (ifa->ifa_addr->sa_family == AF_INET) {
            struct sockaddr_in* saddr = (struct sockaddr_in*)ifa->ifa_addr;
            if (saddr->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {  //不是回环口地址
                char host[NI_MAXHOST] = {0};
                char service[NI_MAXSERV] = {0};
                int ret = getnameinfo((const struct sockaddr*)(ifa->ifa_addr), (socklen_t)(sizeof(struct sockaddr)),
                                       host, NI_MAXHOST,
                                       service, NI_MAXSERV,
                                       NI_NUMERICSERV | NI_NUMERICHOST);
                if(ret == 0){
                    if(regex_search(string(ifa->ifa_name), regex("wlan")) || regex_search(string(ifa->ifa_name), regex("eth"))){
                        localAddress = string(host);
                        find_addr_ok = true;
                        break;
                    }
                }else{
                    perror("getnameinfo");
                }
            }
        }
    }

    freeifaddrs(ifaddr);

    return find_addr_ok;
}



int main(int argc, char* argv[]){

    string localAddress;
    if(getLocalAddress(localAddress)){
        std::cout << "localAddress: " << localAddress << std::endl;
    }

    return 0;
}






